﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Collections;
using System.Runtime.InteropServices;
/*
 * Project Home : http://code.google.com/p/klsudoku
 * Project Owner: ttylikl@gmail.com Email:ttylikl@qq.com
 * Project Blog : http://www.cnblogs.com/ttylikl
 * All Files of this project is free to use , but you should keep the information above when you copy&use it.
 * Infomation Infomation Modify Date: 2009.02.22
 * 
 * */

namespace SudokuPanel
{
 
    public class SudokuGenerator
    {
        private Random ro = new Random();

        public String do_dlx_generator(ref String str)
        {
            puzzle pz=new puzzle();
            dlx_solver ds = new dlx_solver();
            int[] remove = new int[81];
            for (int i = 0; i < 81; ++i)
            {
                remove[i] = i;
            }
            for (int i = 0; i < 81; ++i)
            {
                int ri = ro.Next(0, 81);
                if (ri != i)
                {
                    int t = remove[ri];
                    remove[ri] = remove[i];
                    remove[i] = t;
                }
            }
            while (true)
            {
                pz = new puzzle();
                for (int i = 0; i < 17; ++i)//可以认为17个数必然有解，最少初始数的数独题也有17+的数字
                {
                    int x = remove[i] / 9;
                    int y = remove[i] % 9;
                    int[] cands = pz.m_numbers[x, y].candidates();
                    pz[x+1,y+1] = cands[ro.Next(0, cands.Length - 1)];
                }
                str=ds.do_solve(pz.exportPuzzle(false));
                if (ds.solution_count(pz.exportPuzzle(false))>0)
                    break;
            }
            pz.loadPuzzle(str.ToCharArray());
 
            for (int i = 0; i < 81; ++i)
            {
                int x = remove[i] / 9 + 1 ;
                int y = remove[i] % 9 + 1 ;
                int num = pz[x, y];
                pz[x, y] = 0;
                ds.do_solve(pz.exportPuzzle(false));
                if (ds.solution_count(pz.exportPuzzle(false)) != 1)
                {
                    pz[x, y] = num;
                }
            }
            return pz.exportPuzzle(false);
        }
    //    //取消用PInvoke方式调用DLL生成题目的方式
    //    public String do_c_generator(ref String str)
    //    {
    //        StringBuilder sb = new StringBuilder(1000);
    //        StringBuilder sb2 = new StringBuilder(1000);
    //        c_generate(sb,sb2,1000);
    //        str = sb2.ToString();
    //        return sb.ToString();
    //    }

    //    [DllImport("c_generator.dll",
    //              EntryPoint = "c_generate",
    //              CharSet = CharSet.None,
    //              CallingConvention = CallingConvention.Winapi)]
    //    public static extern int c_generate(StringBuilder sb, StringBuilder sb2, int len);
    }
}